<template>
	<view class="tm-upload  ">
		<tm-dialog v-model="showalert" title="视频预览" :showCancel="false" confirmText="关闭预览" confirmColor="primary text">
			<view>
				<video :src="vedioUrl" style="width: 500rpx;height: 300rpx;" objectFit="contain"></video>
			</view>
		</tm-dialog>
		<view class="flex-col">
			<view v-for="(item,index) in list" :key="index" class="text  border-b-2"  :class="[color_tmeme,black_tmeme?'grey-darken-4 bk ':'',]">
				<view class="flex-between px-24">
					<view 
					class="flex-6 py-18 flex-start  text-overflow text-size-m " 
					>
						<view class="d-inline-block pr-12">
							<tm-icons v-if="item.statusCode==3" :black="black_tmeme" name="icon-check" size="28" color="green"></tm-icons>
							<tm-icons v-if="item.statusCode==0" :black="black_tmeme" name="icon-arrow-alt-from-botto" size="28" color="primary"></tm-icons>
							<tm-icons v-if="item.statusCode==2" :black="black_tmeme" name="icon-times-circle" size="28" color="red"></tm-icons>
							<tm-icons v-if="item.statusCode==4" :black="black_tmeme" name="icon-exclamation-circle" size="28" color="red"></tm-icons>
							<tm-icons v-if="item.statusCode==1" :black="black_tmeme" name="icon-loading" size="28" color="primary"></tm-icons>
						</view>
						<slot name="file" :info="{item}">
							{{item['name']||item['file_name']||item['filename']||item.path}}
						</slot>
					</view>
					<view v-if="!disabled" class="flex-end flex-6" >
						<slot name="right" :info="{data:item,index:index}">
							<view class="d-inline-block pr-24">
									<tm-icons @click="opendoc(item)" :black="black_tmeme" name="icon-eye-fill" size="36" :color="color"></tm-icons>
							</view>
							<view class="d-inline-block pl-12">
									<tm-icons @click="del(index)" :black="black_tmeme" name="icon-times" size="32" color="red"></tm-icons>
							</view>
						</slot>
						
					</view>
				</view>
				<!-- 上传提示语。 -->
				<view v-if="tips&&!disabled" class=" text-size-xs round-b-2 px-24 py-8"
				 :class="[
					 item.statusCode==2||item.statusCode==4?'red text':'',
					 item.statusCode==1||item.statusCode==0?'black text':'',
					 item.statusCode==3?color_tmeme+' text':'',
					 black_tmeme?'bk':''
				 ]"
				 >{{item.status}}</view>
				<!-- 上传的进度。 -->
				<view v-if="item.progress>0&&item.progress!=100&&!disabled" class="tm-upload-pro green"
					:style="{width:item.progress+'%'}"></view>
			</view>
			
			<view  @click="addfile" v-if="list.length<max&&!disabled" class=" grey-lighten-4 ">
				<view class="tm-upload-item-ck border-a-0 flex-center  text py-50" :class="[color_tmeme,black_tmeme?'grey-darken-4 bk':'']">
					<slot name="upload">
						<tm-icons name="icon-plus" size="36" :color="color_tmeme"></tm-icons>
						<text class="text-size-n pl-12">添加文件</text>
					</slot>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	/**
	 * 上传图片组件
	 * @property {Function} change 每一张图片上传成功都传动触发，并返回上传成功的图片列表。
	 * @property {Function} del 删除一张图片时触发，返回当前删除的图片数据。
	 * @property {Number} code = [] 默认：0，服务器上传返回数据中表示成功的标志码。
	 * @property {Number|String} max = [9] 默认：9，最大上传数量
	 * @property {String} fileType = [all|image|file|vedio] 默认：all，上传的文件类型
	 * @property {Array} extension = [*] 默认：[]，上传的文件后缀过滤比如:[".jpg",".doc"]
	 * @property {String|Boolean} disabled = [true|false] 默认：false， 如果禁用，会隐藏上传和删除按钮,只显示已上传的图片。
	 * @property {String} url = [] 默认：""，上传的地址。
	 * @property {Array} filelist = [] 默认：[]，默认上传显示的图片。如果加上filelist.sync的话，会自动更新数据实现双向绑定。类似于v-model;
	 * @property {String} url-key = [] 默认：""，返回数据时，如果返回的是对象。则需要提供对象图像地址的key。默认没有，返回的即是图片地址。
	 * @property {Object} header = [] 默认：{}，上传的头部参数。
	 * @property {String} file-name = [file] 默认：file，上传时的文件key名。
	 * @property {String} name = [] 默认：''，提交表单时的的字段名称标识
	 * @property {Boolean|String} tips = [true|false] 默认：true，是否显示底部的上传提示语。上传中，失败等。
	 * @property {Boolean|String} black = [true|false] 默认：null，暗黑模式。
	 * @property {Boolean|String} auto-upload = [true|false] 默认：false，是否自动上传，即添加完图片后立即上传。
	 * @property {Object} responseStu = [] 默认： {code:'code',//服务器返回的码的字段名称data:'data',//服务上传成功后返回 的数据字段名称msg:'msg'//服务器响应信息的字段名称。}，服务器响应结构字段映射表
	 * @property {Number|String} maxsize = [] 默认：10*1024*1024，最大上传的图片大小，10mb大小
	 * @example <tm-uploadfile></tm-uploadfile>
	 * @description 可以通过refs.组件获得：addfile主动触发添加文件，stopupload停止上传，startupload开始或者继续上传，del删除一张图片。
	 */
	import tmIcons from "@/tm-vuetify/components/tm-icons/tm-icons.vue"
	import tmDialog from "@/tm-vuetify/components/tm-dialog/tm-dialog.vue"
	export default {
		components:{tmIcons,tmDialog},
		name: "tm-uploadfile",
		props: {
			black:{
				type:Boolean|String,
				default:null
			},
			// 最大上传数量，默认9
			max: {
				type: String | Number,
				default: 9
			},
			// 最大上传数量，默认9
			maxsize: {
				type: String | Number,
				default: 10*1024*1024
			},
			// 主题色
			color: {
				type: String,
				default: 'primary'
			},
			
			// 如果禁用，会隐藏上传和删除按钮。
			disabled: String | Boolean,
			// 上传的地址。
			url: {
				type: String,
				default: ''
			},
			// 默认上传显示的图片。如果加上filelist.sync的话，会自动更新数据实现双向绑定。类似于v-model;
			filelist: {
				type: Array,
				default: () => {
					return [];
				}
			},
			
			//返回数据时，如果返回的是对象。则图像地址的key名。默认没有，返回的即是图片地址。
			urlKey:{
				type:String,
				default:''
			},
			// 上传的头部参数。
			header:{
				type:Object,
				default:()=>{
					return {};
				}
			},
			fileType:{
				type:String,//上传的文件类型，默认所有。
				default:'all'
			},
			extension:{
				type:Array,//上传的文件类型，默认所有。
				default:()=>[]
			},
			// 上传时的文件key名。默认file
			fileName:{
				type:String,
				default:'file'
			},
			// 是否显示底部的上传提示语。上传中，失败等。
			tips: {
				type: Boolean|String,
				default: true,
			},
			// 是否自动上传，即添加完图片后立即上传。
			autoUpload: {
				type: Boolean,
				default: false,
			},
			//提交表单时的的字段名称
			name:{
				type:String,
				default:''
			},
			// 跟随主题色的改变而改变。
			fllowTheme:{
				type:Boolean|String,
				default:true
			},
			//定义上传成功返回的code码，默认是0表示上传成功 。
			code:{
				type:Number,
				default:0
			},
			//上成功后，服务器顺应数据的字段映射表。
			responseStu:{
				type:Object,
				default:()=>{
					return {
						code:'code',//服务器返回的码的字段名称
						data:'data',//服务上传成功后返回 的数据字段名称
						msg:'msg'//服务器响应信息的字段名称。
					}
				}
			}
		},
		computed: {
			header_obj:function () {
				return this.header;
			},
			black_tmeme: function() {
				if (this.black !== null) return this.black;
				return this.$tm.vx.state().tmVuetify.black;
			},
			color_tmeme:function(){
				if(this.$tm.vx.state().tmVuetify.color!==null&&this.$tm.vx.state().tmVuetify.color && this.fllowTheme){
					return this.$tm.vx.state().tmVuetify.color;
				}
				return this.color;
			},
		},
		data() {
			return {
				showalert:false,
				list: [],
				vedioUrl:'',
				upObje:null,
			};
		},
		created() {
			
		},
		async mounted() {
			let t = this;
			if (typeof t.filelist === 'object' && Array.isArray(t.filelist)) {
				let plist = [...t.filelist];
				plist.forEach((item, index) => {
					let url = "";
					if (typeof item === 'string') {
						url = item;
					} else if (typeof item === 'object') {
						url = item[t.urlKey]
					}
					t.list.push({
						url: url,
						status: "上传成功",
						progress: 100,
						fileId: t.$tm.guid(),
						statusCode: 3,
						data: item,
					})
				})
			
			}
		},
		methods: {
			opendoc(item){
				this.url="";
				let type = item.type;
				let image = ['jpg','png','jpeg','gif'];
				let video = ['mp4','avi','mov','webm','ogg','flv','m3u8'];
				let doc = ['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx','text','txt'];
				let isSou = [...image,...video,...doc].filter(el=>el==item.type);
				if(isSou.length==0){
					uni.showToast({
						title:"未知文件格式，不支持预览",icon:'none'
					})
					return;
				}
				let imageOpen = image.filter(el=>el==item.type);
				if(imageOpen.length>0){
					this.$tm.preview.previewImg(item.url,[item.url],'url')
					return;
				}
				let videoOpen = video.filter(el=>el==item.type);
				if(videoOpen.length>0){
					this.url = item.url;
					this.showalert = true;
					return;
				}
				let docOpen = doc.filter(el=>el==item.type);
				// #ifdef H5
				uni.showToast({
					title:"不支持预览稿件",icon:'none'
				})
				return;
				// #endif
				if(docOpen.length>0){
					if(item.url.indexOf('http://tmp/')>-1){
						uni.openDocument({
							filePath:item.url
						})
					}else{
						uni.showLoading({
							title:'下载中',
							mask:true
						})
						uni.downloadFile({
							url: item.url, 
							success: (res) => {
								if (res.statusCode !== 200) {
									uni.hideLoading()
									uni.showToast({
										title:"下载失败",
										icon:'error'
									})
									return;
								}
								uni.hideLoading()
								let url = res.tempFilePath;
								uni.openDocument({
									filePath:url
								})
							},
							fail:()=>{
								uni.hideLoading()
								uni.showToast({
									title:"下载失败",
									icon:'error'
								})
							}
						});
					}
					
					
					return;
				}
				
			},
			errorFile(item,index){
				let id = item;
				id['loaderror'] = true;
				this.list.splice(index,1,id)
			},
			//动态添加默认已上传的文件。
			pushFile(list){
				let t= this;
				let plist = list||[];
				plist.forEach((item, index) => {
					let name = "";
					let type = "";
					let url = "";
					if (typeof item === 'string') {
						url = item;
						name = item;
						type = item.substr(item.lastIndexOf(".")+1);
					} else if (typeof item === 'object') {
						url = item[t.urlKey];
						name = item['name']||url;
						type = name.substr(name.lastIndexOf(".")+1);
					}
					t.list.push({
						url: url,
						type:type,
						name:name,
						status: "上传成功",
						progress: 100,
						fileId: t.$tm.guid(),
						statusCode: 3,
						data: item,
					})
				})
			},
			async addfile() {
				if(this.disabled) return;
				let t = this;
				let maxfile = parseInt(this.max) - this.list.length;
				if (maxfile <= 0) {
					this.$tm.toast("已达上传上限");
					return;
				};
				let url = this.url;
				if(!this.upObje){
					this.upObje = new this.$tm.upload.uploadfile({
						opts:{header:this.header_obj,name:this.fileName},
						maxfile:maxfile,
						uploadUrl:url,
						isAuto:this.autoUpload,
						maxsize:this.maxsize,
						code:this.code,
						responseStu:this.responseStu,
						type:this.fileType,
						extension:this.extension
					});
					// 添加已有的图片。
					this.upObje.addfile(this.list);
					this.upObje.success = function(item){
						t.changeSuccess();
					}
				}else{
					this.upObje.setConfig({
						type:this.fileType,
						extension:this.extension,
						maxsize:this.maxsize,maxfile:maxfile,code:this.code,responseStu:this.responseStu,opts:{header:this.header_obj,name:this.fileName}});
				}
				
				let clist = await this.upObje.chooseMPH5weixinFile().catch(e=>{
					console.error(e);
				});
				if(clist){
					t.list = clist;
				}
			},
			// 停止下载
			stopupload(){
				if(this.disabled) return;
				if(this.upObje){
					this.upObje.stop();
				}
			},
			// 继续上传或者开始上传。
			startupload(){
				if(this.disabled) return;
				if(this.upObje){

					this.upObje.start();
				}
			},
			// 删除一张图片。
			del(index) {
				this.$emit("del",this.list[index])
				this.list.splice(index, 1);
				this.changeSuccess();
			},
			// 只有上传成功才会触发change。并更新发送数据。
			changeSuccess() {
				let filelist = [];
				this.list.forEach((item, index) => {
					if (item.statusCode === 3) {
						filelist.push(item.data);
					}
				})
				this.$emit('change', filelist);
				this.$emit('update:filelist', filelist);
			},
			//获取已经上传的图像。
			getFile(){
				let filelist = [];
				this.list.forEach((item, index) => {
					if (item.statusCode === 3) {
						filelist.push(item.data);
					}
				})
				return filelist;
			},
			//清除所有已上传的文件。
			clearAllFile(){
				this.$emit("clear",[])
				this.list=[];
				this.changeSuccess();
			}
		},
	}
</script>

<style lang="scss" scoped>
	
</style>
